package util

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"
)

type MediaFileInfo struct {
	FileFullName string
	HasExif      bool
	TokenTime    time.Time
	ModTime      time.Time
	Dir          string
	FileName     string
	Ext          string
}

func RenameFile(oldName, newName string, isMove bool) (bool, error) {
	dir := GetPathDirectory(newName)
	dirExist, err := IsFileExists(dir)
	if err != nil {
		return false, err
	}
	if !dirExist {
		err := os.MkdirAll(dir, 0777)
		if err != nil {
			return false, err
		}
	}

	newName = GetNewFilename(newName)

	if isMove {
		return MoveFile(oldName, newName)
	} else {
		return CopyFile(oldName, newName)
	}
}

// exists returns whether the given file or directory exists or not
func IsFileExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

//获取路径目录
func GetPathDirectory(name string) string {
	runes := []rune(name)
	l := len(runes)
	for {
		if l == 0 {
			break
		}
		if string(runes[l-1]) == "\\" {
			return string(runes[:l-1])
		}
		l -= 1
	}
	return name
}

//获取一个可用的文件名
func GetNewFilename(name string) string {
	oldName := name
	i := 1
	for {
		fileExist, err := IsFileExists(name)
		if err != nil {
			return name
		}
		if fileExist {
			pos := strings.LastIndex(oldName, ".")
			name = string([]byte(oldName)[:pos]) + fmt.Sprintf(" #%d", i) + path.Ext(oldName)
		} else {
			return name
		}
		i += 1
	}

}

//移动文件
func MoveFile(oldName, newName string) (bool, error) {
	err := os.Rename(oldName, newName)
	if err != nil {
		return false, err
	}
	return true, nil
}

//复制文件
func CopyFile(srcName, dstName string) (bool, error) {
	src, err := os.Open(srcName)
	defer src.Close()
	if err != nil {
		return false, err
	}
	dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return false, err
	}
	_, err = io.Copy(dst, src)
	if err != nil {
		return false, err
	}
	fileInfo, _ := src.Stat()
	dst.Close()
	os.Chtimes(dstName, time.Now(), fileInfo.ModTime())
	return true, nil

}

// 获取文件基本信息
func GetFileBaseInfo(name string) (os.FileInfo, error) {
	fileInfo, err := os.Stat(name)
	if err != nil {
		return fileInfo, err
	}
	return fileInfo, err
}

// 目录遍历返回文件列表 dirPath：目录路径；suffix：文件后缀名；traversal：是否遍历子目录
func SearchFile(dirPath, suffix string, traversal bool) (files []string, err error) {
	if traversal {
		return WalkDir(dirPath, suffix)
	} else {
		return ListDir(dirPath, suffix)
	}
}

//获取指定目录下的所有文件，不进入下一级目录搜索，可以匹配后缀过滤。
func ListDir(dirPath string, suffix string) (files []string, err error) {
	files = make([]string, 0, 10)
	dir, err := ioutil.ReadDir(dirPath)
	if err != nil {
		return nil, err
	}
	PathSep := string(os.PathSeparator)
	suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
	for _, fi := range dir {
		if fi.IsDir() { // 忽略目录
			continue
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) { //匹配文件
			files = append(files, dirPath+PathSep+fi.Name())
		}
	}
	return files, nil
}

//获取指定目录及所有子目录下的所有文件，可以匹配后缀过滤。
func WalkDir(dirPath, suffix string) (files []string, err error) {
	files = make([]string, 0, 30)
	suffix = strings.ToLower(suffix) //忽略后缀匹配的大小写
	err = filepath.Walk(dirPath,
		func(filename string, fi os.FileInfo, err error) error { //遍历目录
			//if err != nil { //忽略错误
			// return err
			//}
			if fi.IsDir() { // 忽略目录
				return nil
			}
			if strings.HasSuffix(strings.ToLower(fi.Name()), suffix) {
				files = append(files, filename)
			}
			return nil
		})
	return files, err
}
